perm filename DVIMAG.C[MF,ALS] blob
sn#771995 filedate 1984-10-12 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00014 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 ∂12-Oct-84 1323 trickey@diablo dvi-imagen
C00004 00003 dvi-imagen.c
C00046 00004 output.c
C00068 00005 error.c
C00071 00006 rotate.c
C00073 00007 special.c
C00079 00008 imPcodes.h
C00081 00009 impress.h
C00083 00010 dvi.h
C00086 00011 c.h
C00088 00012 font.h
C00092 00013 ipr.h
C00096 00014 resfonts.h
C00097 ENDMK
C⊗;
∂12-Oct-84 1323 trickey@diablo dvi-imagen
Received: from SU-AIMVAX.ARPA by SU-AI.ARPA with TCP; 12 Oct 84 13:23:31 PDT
Date: Fri, 12 Oct 84 13:24:17 pdt
From: Howard Trickey <trickey@diablo>
Subject: dvi-imagen
To: als@sail
Here are the files used for the VAX UNIX version of dvi-imagen,
a program that takes dvi files into the format used by imagen,
using pixel versions of the fonts. The file produced by dvi-imagen
needs some additional ascii header information prepended to it before it
is sent to the imagen. DRF probably knows that stuff, but I can help you
later if need be.
The files below are separated by lines of ==='s, with the file name.
The .c programs are C language, the .h files get included in them.
dvi-imagen.c
===============================================
/*
** dvi-imagen.c Imagen driver for DVI format 2
**
** Syntax:
** dvi-imagen [options] <dvi-file>
**
** Description:
** Translates the DVI commands in the <dvi-file> into commands
** for the Imagen ImPrint-10 Laser Printer. These are placed
** into a /tmp file which is then handed to the ipr(1) program.
**
** The -L option takes a shot at Landscape mode.
** The -U option disables centering
** The -I option provides one-inch margins
** The -v option makes the output be in decoded (verbose) form
** -v implies -s
** The -s option makes dvi-imagen refrain from calling ipr(1),
** with Impress output on stdout.
** The -cX option requests X copies (default 1)
** The -d option makes dvi-imagen produce debugging information.
** The -D option gets everything -d does and more, including
** dumping out the glyphs in each font in a readable format.
*/
#include <stdio.h>
#include <curses.h>
#include <pwd.h>
#include "dvi.h"
#include "font.h"
#define MAXFONTS 64 /* Due to 6-bit field in Imagen codes */
/* I may fix this in the next version */
#define PIXELS←PER←INCH 300
#define HARD←XPAGE←OFFSET 160 /* Damn it */
#define PIXELS←PER←LINE (8 * PIXELS←PER←INCH - HARD←XPAGE←OFFSET)
/* 8 inches of printing area */
#define PIXELS←PER←PAGE (11 * PIXELS←PER←INCH)
/* 11 inches of printing area */
#define FONT←DIRECTORY "/usr/stanford/lib/tex82/fonts/pxls"
#define pixel←round(x) ((long) (conv * (double) (x) + 0.5))
#define dvi←round(x) ((long) ((double) (x) / conv + 0.5))
#define one(fp) num (fp, 1)
#define sone(fp) snum(fp, 1)
#define two(fp) num (fp, 2)
#define four(fp) num (fp, 4)
#define sfour(fp) snum(fp, 4)
typedef unsigned char ubyte;
struct frame
{
long pxl←h, dvi←h, pxl←v, dvi←v, w, x, y, z;
};
struct frame *stack;
int stackp;
extern int landscape;
int debug = 0;
int verbose = 0;
int spoolit = 1;
int landscape = 0;
int center = 1;
int inchmargin = 0;
int numcopies = 1;
struct font *fontListHead = NULL;
char job←id[300];
char InputName[300];
int total←pages, maxstack, Xpage←offset, Ypage←offset;
int fontnum = 0;
double conv;
long numerator, denominator, magnification;
char *output←file←name;
char *Usage←str = "Usage: iptex [-U] [-I] [-L] [-v] [-s] [-d] <dvi-file>";
long read←postamble();
unsigned long num();
long snum();
char *malloc();
char *mktemp();
main(argc, argv)
int argc;
char *argv[];
{
FILE *fp;
long last←page; /* file offset of last page of output */
int nc;
while (argv[1][0] == '-')
{
switch (argv[1][1])
{
case 'c':
if ((nc=atoi(&argv[1][2])) > 0) numcopies=nc;
break;
case 's':
spoolit = 0;
break;
case 'd':
debug = 1;
break;
case 'D':
debug = 2;
break;
case 'v':
verbose = 1;
spoolit = 0;
break;
case 'L':
landscape = 1;
break;
case 'U':
center = 0;
break;
case 'I':
inchmargin = 1;
break;
default:
error(Usage←str);
}
argv++;
argc--;
}
if (argc != 2)
error(Usage←str);
if ((fp = fopen(argv[1], "r")) == NULL) {
char longername[256];
strcpy (longername, argv[1]);
strcat (longername, ".dvi");
if ((fp = fopen (longername, "r")) == NULL)
error("dvi-imagen: Can't open %s", argv[1]);
}
strcpy (InputName, argv[1]);
process←preamble(fp);
find←postamble(fp);
last←page = read←postamble(fp);
start←output();
do←pages(fp, last←page);
finish←output();
}
!
/*
** process←preamble(fp)
**
** fp is a FILE pointer for a DVI file which is positioned at the
** beginning.
**
** process←preamble reads the information in the preamble and stores
** it into global variables for later use.
*/
process←preamble(fp)
FILE *fp;
{
ubyte k;
double fraction;
if (one(fp) != PRE)
error("dvi-imagen: DVI file doesn't start with preamble");
if (one(fp) != 2)
error("dvi-imagen: Wrong version of DVI output for this program");
numerator = four(fp);
denominator = four(fp);
magnification = four(fp);
fraction = (((double) numerator * magnification)
/ ((double) denominator * 1000.));
conv = ((fraction / 100000) / 2.54) * PIXELS←PER←INCH;
k = one(fp);
fread(job←id, sizeof(char), k, fp);
job←id[k] = '\0';
}
!
/*
** find←postamble(fp)
**
** fp is a FILE pointer for a DVI-format file. find←postamble locates
** the beginning of the postamble and leaves the file ready to start
** reading at that location.
*/
find←postamble(fp)
FILE *fp;
{
ubyte byte;
long offset = -4; /* At least 4 TRAILERS */
do
{
offset--;
fseek(fp, offset, 2);
byte = one(fp);
} while(byte == TRAILER);
if (byte != 2)
error("dvi-imagen: Wrong version of DVI output for this program");
offset -= 4;
fseek(fp, offset, 2);
fseek(fp, four(fp), 0);
}
!
/*
** long
** read←postamble(fp)
**
** fp is a FILE pointer for a DVI-format file. read←postamble reads the
** information in the postamble, storing it into global variables.
** It also takes care of reading in all of the PXL files for the fonts
** used in the job.
**
** read←postamble returns the file offset of the beginning of the last
** page of DVI output.
*/
long
read←postamble(fp)
FILE *fp;
{
long last←page;
long tallest, widest;
ubyte cmnd;
if (one(fp) != POST)
error("dvi-imagen: Postamble doesn't begin with POST");
last←page = four(fp);
if (numerator != four(fp)
|| denominator != four(fp)
|| magnification != four(fp))
error("dvi-imagen: Postamble doesn't match preamble");
tallest = four(fp);
if (!landscape) {
Ypage←offset = (PIXELS←PER←PAGE - pixel←round(tallest)) / 2;
widest = four(fp);
Xpage←offset = (PIXELS←PER←LINE - pixel←round(widest)) / 2
+ HARD←XPAGE←OFFSET;
} else {
Ypage←offset = (PIXELS←PER←LINE - pixel←round(tallest))/2
+ HARD←XPAGE←OFFSET;
widest = four(fp);
Xpage←offset = (PIXELS←PER←PAGE - pixel←round(widest))/2;
}
if (!center) Ypage←offset = Xpage←offset = 0;
if (inchmargin) Ypage←offset = Xpage←offset = PIXELS←PER←INCH;
maxstack = two(fp);
total←pages = two(fp);
if (debug)
remark("tall, wide, po, stk, pages = %d, %d, %d, %d, %d",
tallest, widest, Xpage←offset, maxstack, total←pages);
do
{
switch(cmnd = one(fp))
{
case FNTDEF1:
case FNTDEF2:
case FNTDEF3:
case FNTDEF4:
define←font(fp, cmnd);
break;
case POSTPOST:
break;
default:
error("dvi-imagen: Non-fntdef cmnd found in postamble");
}
} while (cmnd != POSTPOST);
return (last←page);
}
!
/*
** define←font(fp, cmnd)
**
** fp is a FILE pointer for a DVI file which is positioned right after
** a fntdef command. The opcode for the command is in cmnd.
**
** define←font reads the rest of the fntdef command and then reads in
** the specified PXL file, adding it to the global linked-list holding
** all of the fonts used in the job.
*/
define←font(fp, cmnd)
FILE *fp;
ubyte cmnd;
{
struct font *fontp;
long checksum;
int len;
char fontname[513];
if (fontnum >= MAXFONTS)
error("dvi-imagen: Too many fonts. Maximum is %d", MAXFONTS);
fontp = (struct font *) malloc( sizeof(struct font) );
if (fontp == NULL)
error("dvi-imagen: Out of memory while reading font %d", fontnum);
fontp->next = fontListHead;
fontListHead = fontp;
fontp->TeXnumber = num(fp, cmnd - FNTDEF1 + 1);
fontp->Inumber = fontnum++;
checksum = four(fp);
fontp->scale = four(fp);
fontp->design = four(fp);
len = one(fp) + one(fp);
fread(fontname, sizeof(char), len, fp);
fontname[len] = '\0';
strcpy(fontp->fontname, fontname);
read←pxl←file(fontp, fontname);
if (debug > 1)
dump←font(fontp, fontname);
}
!
/*
** read←pxl←file(fontp, fontname)
**
** fontp points to a (struct font) which has been partially initialised
** with the information in the DVI-file FNTDEF command. fontname is the
** name of a font.
**
** read←pxl←file constructs the expected name of the font's PXL file
** from the info in *fontp and fontname. It then reads the glyph
** bitmaps into memory.
**
** Note: the 'size' of a font (i.e. the 1200 in 'cmr10.1200pxl') is
** given by the following formula (rounded):
**
** scaled-size PIXELS←PER←INCH
** ----------- * --------------- * 1000
** design-size 200
**
** In the actual implementation, scaled-size/design-size hasn't been
** stored with sufficient precision, hence the messing around to find
** its actual value.
*/
char *rotate();
read←pxl←file(fontp, fontname)
struct font *fontp;
char *fontname;
{
char filename[1025];
FILE *pxlfp;
int unmodsize;
float realsize;
int size;
long checksum, magnify,
design←size, font←dir←ptr, pxl←id←word;
long glyph←ptr[128]; /* Seek locations of each glyph */
int i, j, k;
realsize = (magnification/1000.)*((float) fontp->scale / fontp->design);
unmodsize = (realsize * 1000) + 0.5;
/* a real hack to correct for rounding in some cases -- rkf */
if(unmodsize==1095) realsize = 1.095445; /* stephalf */
else if(unmodsize==1315) realsize=1.314534; /* stepihalf */
else if(unmodsize==2074) realsize=2.0736; /* stepiv */
else if(unmodsize==2488) realsize=2.48832; /* stepv */
else if(unmodsize==2986) realsize=2.985984; /* stepiv */
/* the remaining magnification steps are represented with sufficient
accuracy already */
size = (realsize * PIXELS←PER←INCH * 5) + 0.5;
sprintf(filename, "%s.%dpxl", fontname, size);
if ((pxlfp = fopen(filename, "r")) == NULL)
{
sprintf(filename, "%s/%s.%dpxl", FONT←DIRECTORY, fontname, size);
if ((pxlfp = fopen(filename, "r")) == NULL)
{
remark("scale = %d, design = %d",fontp->scale, fontp->design);
fperror("Can't find font: \"%s\"", filename);
}
}
fseek(pxlfp, - (5 * 4L), 2); /* Seek to trailer info */
checksum = four(pxlfp);
magnify = four(pxlfp);
design←size = four(pxlfp);
font←dir←ptr = four(pxlfp) * 4;
pxl←id←word = four(pxlfp);
fseek(pxlfp, font←dir←ptr, 0); /* Seek to font directory */
fontp->bc = 0;
fontp->ec = 127;
for (i=0; i < 128; i++)
{
fontp->state[i] = Ready;
fontp->W[i] = two(pxlfp);
fontp->H[i] = two(pxlfp);
fontp->X[i] = two(pxlfp);
fontp->Y[i] = two(pxlfp);
glyph←ptr[i] = four(pxlfp) * 4;
/*
** The TFM-width word is kind of funny in the units
** it is expressed in. It works this way:
**
** If a glyph has width 'w' in a font with design-size
** 'd' (both in same units), the TFM-width word is
**
** (w/d) * 2↑20
**
** Therefore, in order to find the glyph width in
** DVI units (1 / 2↑16 points), we take the design-size
** 'd' (in DVI's), the magnification 'm' of the PXL file
** and the TFM-width word 't' to the width (in DVI's)
** as follows:
**
** dmt
** w = -----
** 2↑20
**
** But the magnification of the PXL file is just the
** scaled size 's' over the design size, so the final
** expression for the width is
**
** st
** w = ----
** 2↑20
**
*/
#ifndef UNDEFINED
fontp->dvi←adv[i] =
((double) fontp->scale * four(pxlfp)) / (1 << 20);
#else
fontp->dvi←adv[i] =
((double) fontp->design * four(pxlfp)) / (1 << 20);
#endif
fontp->pxl←adv[i] = pixel←round(fontp->dvi←adv[i]);
}
for (i=0; i < 128; i++)
{
int real←bytes←wide = (fontp->W[i] + 7) / 8;
int file←bytes←wide = ((fontp->W[i] + 31) / 32) * 4;
char *ptr;
char junk;
ptr = fontp->Glyph[i] = malloc(fontp->H[i] * real←bytes←wide);
if (ptr == NULL)
error("Out of memory while reading character %d of font %s\n",
i, fontname);
fseek(pxlfp, glyph←ptr[i], 0);
for (j=0; j < fontp->H[i]; j++)
{
for (k=0; k < file←bytes←wide; k++)
{
if (k < real←bytes←wide)
*(ptr++) = one(pxlfp);
else
junk = one(pxlfp);
}
}
if (landscape) {
char *holdglyph;
int width,height,x,y;
holdglyph = fontp->Glyph[i];
fontp->Glyph[i] = rotate(holdglyph, fontp->H[i], fontp->W[i]);
/* free(holdglyph); */
width = fontp->W[i]; height=fontp->H[i];
x = fontp->X[i]; y=fontp->Y[i];
fontp->W[i] = height; fontp->H[i] = width;
fontp->X[i] = height-y; fontp->Y[i] = x;
}
}
fclose(pxlfp);
}
!
/*
** start←output()
**
** Arrange for the stuff at the beginning of the output to the Imagen
** to be sent out, including the jobid, etc.
**
*/
start←output()
{
char *buffer[50];
struct passwd *pwbuf, *getpwuid();
pwbuf = getpwuid(getuid());
sprintf(buffer, " (%s [%d pages])", pwbuf->pw←name, total←pages);
strcat(job←id, buffer);
if (spoolit) {
output←file←name = mktemp("/tmp/dviXXXXXX");
ImPressStart(output←file←name, job←id, verbose);
}
else
ImPressStart((char *)0, job←id, verbose);
}
!
/*
** do←pages(fp, last←page)
**
** Process the pages in the FILE fp. last←pages is the offset of the
** last page. (We do the pages in reverse order, of course.)
**
*/
#define PXL←H stack[stackp].pxl←h
#define PXL←V stack[stackp].pxl←v
#define DVI←H stack[stackp].dvi←h
#define DVI←V stack[stackp].dvi←v
#define WW stack[stackp].w
#define XX stack[stackp].x
#define YY stack[stackp].y
#define ZZ stack[stackp].z
#define nope(str) error("Can't hack %s", str)
#define correct() diff = PXL←H - pixel←round(DVI←H); \
if (diff < 0) \
{ \
while (diff++) \
ImPressMplus(); \
} \
else if (diff > 0) \
{ \
while (diff--) \
ImPressMminus(); \
} \
PXL←H = pixel←round(DVI←H);
do←pages(fp, last←page)
FILE *fp;
long last←page;
{
char input←left = 1;
long next←page;
struct font *curr←font;
int diff;
struct font *ptr;
ubyte ch;
stack = (struct frame *) malloc( sizeof(struct frame) * (maxstack+1));
if (stack == NULL)
error("Can't allocate stack space.");
fseek(fp, last←page, 0);
while (input←left)
{
ch = one(fp);
if (ch <= SETCHAR0 + 127)
{
ImPressCharacter(ch);
DVI←H += curr←font->dvi←adv[ch];
PXL←H += curr←font->pxl←adv[ch];
correct();
}
else if (FNTNUM0 <= ch && ch <= FNTNUM0 + 63)
{
for (ptr = fontListHead; ptr != NULL; ptr = ptr->next)
if (ptr->TeXnumber == ch - FNTNUM0)
break;
if (ptr == NULL)
error("FNTNUM to non-existant font #%d", ch - FNTNUM0);
curr←font = ptr;
ImPressFont(ptr);
}
else
{
long a, b;
switch (ch)
{
case SET1:
nope("SET1");
break;
case SETRULE:
a = sfour(fp); b = sfour(fp);
if (a > 0 && b > 0)
{
correct();
ImPressRule(pixel←round(b), pixel←round(a));
}
DVI←H += b;
diff = pixel←round(DVI←H);
ImPressMove(diff - PXL←H);
PXL←H = diff;
break;
case PUT1:
nope("PUT1");
break;
case PUTRULE:
a = sfour(fp); b = sfour(fp);
if (a > 0 && b > 0)
{
correct();
ImPressRule(pixel←round(b), pixel←round(a));
}
break;
case NOP:
break;
case BOP:
a = four(fp);
if (debug)
remark("Beginning page %d", a);
for (a=0; a < 9; a++)
four(fp);
next←page = sfour(fp);
stackp = 0;
DVI←H = dvi←round(Xpage←offset);
PXL←H = Xpage←offset;
DVI←V = dvi←round(Ypage←offset);
PXL←V = Ypage←offset;
WW = XX = YY = ZZ = 0;
curr←font = NULL;
ImPressBeginPage();
ImPressSetX(PXL←H);
break;
case EOP:
ImPressEndPage();
if (stackp > 0)
remark("Stack not empty at EOP; stackp = %d",
stackp);
if (next←page < 0)
input←left = 0;
else
fseek(fp, next←page, 0);
break;
case PUSH:
stackp++;
if (stackp > maxstack)
error("More PUSHes than were promised");
stack[stackp] = stack[stackp - 1];
break;
case POP:
stackp--;
if (stackp < 0)
error("More POPs than PUSHes");
ImPressSetX(PXL←H);
ImPressSetY(PXL←V);
break;
case RIGHT1:
case RIGHT2:
case RIGHT3:
case RIGHT4:
DVI←H += snum(fp, ch - RIGHT1 + 1);
diff = pixel←round(DVI←H);
ImPressMove(diff - PXL←H);
PXL←H = diff;
break;
case X0:
case X1:
case X2:
case X3:
case X4:
if (ch != X0)
{
XX = snum(fp, ch - X0);
ImPressSetSpace(pixel←round(XX));
}
ImPressSpace();
DVI←H += XX;
PXL←H += pixel←round(XX);
correct();
break;
case W0:
case W1:
case W2:
case W3:
case W4:
if (ch != W0)
WW = snum(fp, ch - W0);
DVI←H += WW;
diff = pixel←round(DVI←H);
ImPressMove(diff - PXL←H);
PXL←H = diff;
break;
case Y0:
case Y1:
case Y2:
case Y3:
case Y4:
if (ch != Y0)
YY = snum(fp, ch - Y0);
DVI←V += YY;
PXL←V = pixel←round(DVI←V);
ImPressSetY(PXL←V);
break;
case Z0:
case Z1:
case Z2:
case Z3:
case Z4:
if (ch != Z0)
ZZ = snum(fp, ch - Z0);
DVI←V += ZZ;
PXL←V = pixel←round(DVI←V);
ImPressSetY(PXL←V);
break;
case DOWN1:
case DOWN2:
case DOWN3:
case DOWN4:
DVI←V += snum(fp, ch - DOWN1 + 1);
PXL←V = pixel←round(DVI←V);
ImPressSetY(PXL←V);
break;
case FNT1:
case FNT2:
case FNT3:
case FNT4:
a = num(fp, ch - FNT1 + 1);
for (ptr = fontListHead; ptr != NULL; ptr = ptr->next)
if (ptr->TeXnumber == a)
break;
if (ptr == NULL)
error("FNT to non-existant font #%d", a);
curr←font = ptr;
ImPressFont(ptr);
break;
case XXX1:
case XXX2:
case XXX3:
case XXX4:
/*nope("XXXX");*/
a = num(fp, ch-XXX1+1);
if(a > 0)
DoSpecial (a, fp);
break;
case FNTDEF1:
case FNTDEF2:
case FNTDEF3:
case FNTDEF4:
fseek(fp, 12 + ch - FNTDEF1 + 1, 1);
a = one(fp) + one(fp);
fseek(fp, a, 1);
break;
case PRE:
error("Can't Happen: PRE encountered.");
break;
case POST:
error("Can't Happen: POST encountered.");
break;
case POSTPOST:
error("Can't Happen: POSTPOST encountered.");
break;
default:
error("Unknown Op-code: %d; Offset: %d",
ch, ftell(fp));
} /* end switch*/
} /* end else (ch not a SETCHAR or FNTNUM) */
} /* end while */
}
!
/*
** finish←output()
**
** Wrap it up. This routine does not return, since ImPressSendIt()
** doesn't.
**
*/
finish←output()
{
ImPressFinish();
if (! spoolit)
exit(0);
ImPressSendIt(output←file←name, NULL, InputName,
total←pages, numcopies, 0, 0);
}
!
/*
** num(fp, size) snum(fp, size)
**
** Read size bytes from the FILE fp, constructing them into a
** signed/unsigned integer.
**
*/
unsigned long
num(fp, size)
FILE *fp;
int size;
{
int i;
long x;
x = 0;
for (i=0; i < size; i++)
{
x = x * 256 + (unsigned) fgetc(fp);
}
return(x);
}
long
snum(fp, size)
FILE *fp;
int size;
{
int i;
long x;
x = fgetc(fp) & 0377;
if (x & 0200)
x -= 256;
for (i=1; i < size; i++)
{
x = x * 256 + (unsigned) fgetc(fp);
}
return(x);
}
!
/*
** dump←font(fontp, fontname)
**
** Debugging routine which prints a representation of the information
** read from a PXL file into a 'struct font'.
**
*/
dump←font(fontp, fontname)
struct font *fontp;
char *fontname;
{
int i, j, k, l;
printf("\n+++++DUMP OF FONT \"%s\": ", fontname);
printf("TeXnumber, Inumber, scale, design = %d, %d, %d, %d\n",
fontp->TeXnumber,
fontp->Inumber,
fontp->scale,
fontp->design);
printf("\tfontp = %o\n", fontp);
for (i=0; i < 128; i++)
{
char *ptr;
printf("\nCharacter %d (%s): ", i, unctrl(i));
printf("H, W, X, Y = %d, %d, %d, %d\n",
fontp->H[i],
fontp->W[i],
fontp->X[i],
fontp->Y[i]);
printf("\t\tdvi←adv, pxl←adv = %d, %d\n\n",
fontp->dvi←adv[i],
fontp->pxl←adv[i]);
ptr = fontp->Glyph[i];
for (j=0; j < fontp->H[i]; j++)
{
for (k=0; k < (fontp->W[i] + 7) / 8; k++)
{
for (l=7; l >= 0; l--)
{
if (*ptr & (1 << l))
putchar('@');
else
putchar(' ');
}
ptr++;
}
putchar('\n');
}
}
}
output.c
===============================================
/*
* output.c - implements the ImPress output primitives
* This is the verbose (decoded) version,
* along with the encoded version, default unless
*
*
* written by Bill Nowicki, September 1981
* Stanford University
*
* January 1982 Bill Nowicki
* - Added page buffering
* - Added glyph deletion
*/
# include <stdio.h>
# include "font.h"
# include "imPcodes.h"
# include "ipr.h"
# include "impress.h"
static struct font *CurrentFont = NULL;
static FILE *imPressFile = NULL;
static int Verbose = 0;
static int MemoryAvailable = GlyphSize;
static int MemoryNeeded = 0;
extern int landscape;
/*
* The page buffer. A list of Glyphs, i.e. (font,char) pairs
* that are needed on this page, and a list of the actual typesetting
* commands.
*/
static struct font *GlyphTable[GlyphsPerPage];
static char GlyphChars[GlyphsPerPage];
static char PageBuffer[InputSize];
static int GlyphPointer = 0, PagePointer = 0;
ImPressPutc( c )
{
/*
* Put the indicated character into the page buffer
*/
if (PagePointer>=InputSize) fprintf( stderr, "Input Area overflow\n");
PageBuffer[PagePointer++] = c;
}
ImPressBufWord( w )
{
/*
* output a (big-endian) word to the ImPress page buffer
*/
ImPressPutc( (w>>8)&0377 );
ImPressPutc( (w)&0377 );
}
ImPressPrintf( s, arg1, arg2, arg3, arg4, arg5 )
{
/*
* printf the string with arguments into the page buffer
*/
char buf[512];
int len;
sprintf( buf, s, arg1, arg2, arg3, arg4, arg5 );
len = strlen(buf);
if (PagePointer+len>=InputSize) fprintf( stderr, "Input Area overflow\n");
strncpy( PageBuffer+PagePointer, buf, len);
PagePointer += len;
}
ImPressFont( f )
struct font *f;
{
/*
* switch to font f
*/
if (CurrentFont == f) return;
if (Verbose) ImPressPrintf( "@F %d@", f->Inumber );
else {
ImPressPutc( AF );
ImPressPutc( f->Inumber );
}
CurrentFont = f;
}
ImPressMplus()
{
if (Verbose)
ImPressPrintf("@MPLUS@");
else
ImPressPutc( AMP );
}
ImPressMminus()
{
if (Verbose)
ImPressPrintf("@MMINUS@");
else
ImPressPutc( AMM );
}
ImPressMove( deltaX )
{
/*
* Move the X (major axis) coordinate
*/
if (-128 <= deltaX && deltaX <= 127)
{
if (Verbose) ImPressPrintf( "@M %d@\n", deltaX);
else {
ImPressPutc( AM );
ImPressPutc( deltaX );
ImPressPutc( AM );
}
}
else
{
if (Verbose) ImPressPrintf( "@H %d 1@\n", deltaX);
else {
ImPressPutc( AH );
ImPressPutc( (deltaX >> 7) & 0377 );
ImPressPutc( (deltaX << 1) & 0376 | 01 );
}
}
}
ImPressSetX( x )
{
/*
* set the X (major axis) coordinate
*/
if (Verbose) ImPressPrintf( "@H %d 0@\n", x);
else {
ImPressPutc( AH );
ImPressPutc( (x>>7)&0377 );
ImPressPutc( (x<<1)&0376 );
}
}
ImPressSetSpace( s )
{
/*
* set the "word space" value
*/
if (Verbose) ImPressPrintf( "@SETSP %d@\n", s);
else {
ImPressPutc( ASETSP );
ImPressBufWord( s );
}
}
ImPressSpace()
{
/*
* do a default word space
*/
if (Verbose) ImPressPrintf( "@SP0@\n" );
else ImPressPutc( ASP0 );
}
ImPressSetY(y)
{
/*
* set the Y (minor axis) coordinate
*/
if (Verbose) ImPressPrintf( "@V %d 0@\n", y);
else {
ImPressPutc( AV );
ImPressPutc( (y>>7)&0377 );
ImPressPutc( (y<<1)&0376 );
}
}
ImPressCharacter( c )
char c;
{
/*
* Output the character c in the current font at the current
* position. First we check its state (loaded, wanted, etc.)
*/
switch (CurrentFont->state[c])
{
case Ready:
CurrentFont->state[c]=Wanted;
GlyphChars[GlyphPointer ]=c;
GlyphTable[GlyphPointer++]=CurrentFont;
MemoryNeeded += ImPressSize( CurrentFont, c );
break;
case Loaded:
CurrentFont->state[c]=Kept;
GlyphChars[GlyphPointer ]=c;
GlyphTable[GlyphPointer++]=CurrentFont;
break;
case Wanted:
case Kept:
case InProm:
break;
default:
remark("Weird state for character %d in font %s\n",
c, CurrentFont->fontname );
abort();
}
if (Verbose && c=='@')
ImPressPrintf( "@AT@" );
else
ImPressPutc( c );
}
ImPressGlyph( f, c )
struct font *f;
unsigned char c;
{
register char *glyph = f->Glyph[c];
int bytes = (f->W[c]+7) / 8;
int row, col;
/*
* send the indicated glyph in the font f to the Imprint file.
* "Small" glyphs have all dimensions less than eight bits.
*/
if (f->W[c] == 0 || f->H[c] == 0)
return;
if (Verbose)
{
if ( abs(f->W[c]) < 128 && abs(f->H[c]) < 128 &&
abs(f->X[c]) < 128 && abs(f->Y[c]) < 128 )
fprintf( imPressFile, "@SGLY" );
else fprintf( imPressFile, "@BGLY" );
fprintf( imPressFile, " 0 %d %d %d %d %d %d %d\n", f->Inumber, c,
f->pxl←adv[c], f->W[c], f->X[c],
f->H[c], f->Y[c]);
fprintf( imPressFile, "f = %o, f->TeXnumber = %d\n", f, f->TeXnumber);
for (row=0; row < f->H[c]; row++)
{
for (col=0; col<bytes; col++)
{
static char map[] = { '.', 'O' };
putc( map[ (*glyph >> 7) & 1 ], imPressFile );
putc( map[ (*glyph >> 6) & 1 ], imPressFile );
putc( map[ (*glyph >> 5) & 1 ], imPressFile );
putc( map[ (*glyph >> 4) & 1 ], imPressFile );
putc( map[ (*glyph >> 3) & 1 ], imPressFile );
putc( map[ (*glyph >> 2) & 1 ], imPressFile );
putc( map[ (*glyph >> 1) & 1 ], imPressFile );
putc( map[ (*glyph ) & 1 ], imPressFile );
if (col&1) putc( ' ', imPressFile );
glyph++;
}
if (bytes&1) fprintf( imPressFile, "........" );
putc( '\n', imPressFile );
}
fprintf( imPressFile, "@\n" );
}
else
{
/*
* the encoded form of glyph loading
*/
int rotation;
if (landscape) rotation = 0100; else rotation = 0;
if ( abs(f->W[c]) < 128 && abs(f->H[c]) < 128 &&
abs(f->X[c]) < 128 && abs(f->Y[c]) < 128 )
{
int temp;
putc( ASGLY, imPressFile );
putc(rotation | (f->Inumber>>1), imPressFile );
putc( ( (f->Inumber&1)<<7)|c, imPressFile );
putc( f->pxl←adv[c], imPressFile );
putc( f->W[c], imPressFile );
putc( f->X[c], imPressFile );
putc( f->H[c], imPressFile );
putc( f->Y[c], imPressFile );
}
else
{
putc( ABGLY, imPressFile );
putc(rotation | (f->Inumber>>1), imPressFile );
putc( ((f->Inumber&1)<<7)|c, imPressFile );
ImPressPutWord( f->pxl←adv[c] );
ImPressPutWord( f->W[c] );
ImPressPutWord( f->X[c] );
ImPressPutWord( f->H[c] );
ImPressPutWord( f->Y[c] );
}
fwrite( glyph, 1, f->H[c]*bytes, imPressFile );
}
f->state[c] = Loaded;
}
ImPressRule( w, h )
{
/*
* draw a rule (rectangle) at current point with given dimensions
*/
if (Verbose)
{
if ( abs(w) < 127 && abs(h) < 127 )
ImPressPrintf( "@SRULE" );
else ImPressPrintf( "@BRULE" );
ImPressPrintf( " %d %d %d@\n", w, h, -h);
return;
}
if ( abs(w) < 127 && abs(h) < 127 )
{
ImPressPutc( ASRULE );
ImPressPutc( w );
ImPressPutc( h );
ImPressPutc(-h );
return;
}
ImPressPutc( ABRULE );
ImPressBufWord( w );
ImPressBufWord( h );
ImPressBufWord(-h );
}
ImPressPutWord( w )
{
/*
* output a (big-endian) word to the ImPress file
*/
putc( (w>>8)&0377, imPressFile );
putc( (w)&0377, imPressFile );
}
ImPressStart( fileName, jobID, verbosity )
char *fileName;
char *jobID;
int verbosity;
{
/*
* open the indicated file name for imPress output
* Verbosity is true to use the Verbose (decoded) mode.
* Here we write a dummy job name and ImPress version.
* Returns nonzero if it cannot open the file.
*/
if (fileName == (char *)0)
imPressFile = stdout;
else
imPressFile = fopen( fileName, "w" );
if (imPressFile==NULL)
{
if (debug) printf( "Unable to open %s\n", fileName );
return(TRUE);
}
Verbose = verbosity;
#ifdef OLDIMAGEN
fprintf( imPressFile, "2 %s", jobID );
putc( 0, imPressFile );
fprintf( imPressFile, "12345678");
#endif
if (landscape)
{
if(Verbose)
{
fprintf(imPressFile,"@SET-HV-SYSTEM");
fprintf(imPressFile," %o\n",0101);
}
else
{
fprintf(imPressFile,"%c%c",AMS,0101);
}
}
MemoryNeeded = 0;
MemoryAvailable = GlyphSize;
return(FALSE);
}
ImPressBeginPage()
{
/*
* begin a page of an imPress file
*/
PagePointer = 0;
GlyphPointer = 0;
}
ImPressEndPage()
{
/*
* end a page of an impress file.
*
* First we delete glyphs we do not use on this page if necessary,
* then output all the glyphs we need, then finally dump the Page buffer.
*/
register char *glyphc;
register struct font **fp;
if (debug)
printf( "Begin page, Needed = %d, available = %d\n",
MemoryNeeded, MemoryAvailable );
if (MemoryNeeded >= MemoryAvailable) ImPressDeleteGlyphs();
for (glyphc=GlyphChars, fp=GlyphTable; glyphc < GlyphChars+GlyphPointer;
glyphc++, fp++)
switch ( (*fp)->state[ *glyphc] )
{
case Wanted: ImPressGlyph( *fp, *glyphc );
default: (*fp)->state[ *glyphc ] = Loaded;
}
MemoryAvailable -= MemoryNeeded;
if (Verbose) fprintf( imPressFile, "@PAGE@\n" );
else putc( APAGE, imPressFile );
fwrite( PageBuffer, 1, PagePointer, imPressFile );
if (Verbose) fprintf( imPressFile, "@END@\n" );
else putc( AEND, imPressFile );
MemoryNeeded = 0;
}
ImPressFinish()
{
/*
* End and close out the imPress file
*/
if (Verbose) fprintf( imPressFile, "@EOF@" );
else putc( AEOF, imPressFile );
fclose( imPressFile );
}
ImPressSize( f, c )
register struct font *f;
register char c;
{
/*
* Returns the size of a glyph in the ImPrint's memory.
* VERY dependent on the controller code.
*/
register int size;
int bytes = (f->W[c]+7)/8;
if ( ( f->pxl←adv[c] | f->W[c] | f->H[c] | abs(2*f->X[c]) | abs(2*f->Y[c]) ) < 256 )
size = 12;
else size = 16;
size += bytes*f->H[c];
if (bytes&1) size += f->H[c];
if (bytes<=2 && f->H[c]&1) size += bytes;
return(size);
}
ImPressDeleteGlyphs()
{
/*
* Make a pass through all the fonts we have loaded,
* deleting those glyphs that are loaded but not needed onthis page.
*/
register struct font *f;
register char c;
for (f=fontListHead; f; f=f->next)
for (c=f->bc;c<=f->ec;c++)
if (f->state[c]==Loaded)
{
if (Verbose)
fprintf( imPressFile, "@DELG 0 %d %d @\n" , f->Inumber, c );
else
{
putc( ADELG, imPressFile );
putc( f->Inumber>>1, imPressFile );
putc( (f->Inumber&1)<<7|c, imPressFile );
}
MemoryAvailable += ImPressSize( f, c );
f->state[c] = Ready;
}
if (debug)
printf( "After Deleting glyphs, Memory Needed = %d bytes, Available = %d\n",
MemoryNeeded, MemoryAvailable );
}
ImPressSendIt( fileName, banner, inputName, numberPages,
numberCopies, writeFlag, mailFlag)
char *fileName; /* name of temporary file */
char *banner; /* banner */
char *inputName; /* name of input file */
int numberPages; /* hint of length */
int numberCopies; /* number of copies wanted */
int writeFlag; /* write when done */
int mailFlag; /* mail when done */
{
/*
* Use the ipr spooler to send fileName to an ImPress printer.
* Use banner as the tag for the spooler, or inputName if banner is null.
* Note that this routine execs, so it should normally never return.
*/
char *tag;
char pages[20], copies[20];
char *args[20];
int count = 0;
if (banner) tag = banner;
else if (inputName) tag = inputName;
else tag = "stdin";
args[count++] = "ipr";
if (debug) args[count++] = "-d";
args[count++] = "-Limpress";
args[count++] = "-Djobheader on";
args[count++] = "-r";
args[count++] = "-t";
args[count++] = tag;
if (numberPages>0)
{
sprintf( pages, "-p%d", numberPages );
args[count++] = pages;
}
if (numberCopies>0)
{
sprintf( copies, "-c%d", numberCopies );
args[count++] = copies;
}
if (mailFlag) args[count++] = "-m";
if (writeFlag) args[count++] = "-n";
args[count++] = fileName;
args[count++] = NULL;
if (debug)
{
int i;
printf( "Command line: " );
for (i=0; i<count; i++) printf( " %s", args[i] );
putchar( '\n' );
fflush(stdout);
}
execv( COMMAND, args );
fperror("Couldn't execute ipr. ImPress file in %s",fileName);
}
error.c
===============================================
/*********************************************************************
function: error
description: Error message routines
programmer: Alan S. Watt
history:
11/04/81 original version
07/17/82 fixes for lint
08/10/82 modest cleanup before posting.
*********************************************************************/
#ifndef lint
static char Sccsid[] = "@(#)error.c 1.1";
#endif !lint
#include <stdio.h>
#define NOTOK (-1)
/* VARARGS1 */
error (mesg, args)
char *mesg;
{
←doprnt (mesg, &args, stderr);
putc ('\n', stderr);
exit (NOTOK);
}
extern errno;
extern sys←nerr;
extern char *sys←errlist[];
#ifdef lint
int errno;
int sys←nerr;
char *sys←errlist[1];
#endif lint
static char ehuh[] = "Unknown System Error";
/* VARARGS1 */
fperror (mesg, args)
char *mesg;
{
char *err = ((unsigned)errno >= sys←nerr ? ehuh : sys←errlist[errno]);
←doprnt (mesg, &args, stderr);
fprintf (stderr, ": %s\n", err);
exit (NOTOK);
}
/*VARARGS1*/
remark (mesg, args)
char *mesg;
{
←doprnt (mesg, &args, stderr);
putc ('\n',stderr);
}
/*VARARGS1*/
fpremark (mesg, args)
char *mesg;
{
char *err = ((unsigned)errno >= sys←nerr ? ehuh : sys←errlist[errno]);
←doprnt (mesg, &args, stderr);
fprintf (stderr, ":%s\n", err);
}
rotate.c
===============================================
char *malloc();
char *rotate (glyph, ht, wd) char *glyph; int ht, wd;
{
int byteswide;
int oldwidth;
int byteoff, bitmask, outbitoff, outbit, posn, i;
char *opt, *outptr;
if (ht == 0 || wd == 0) return (glyph);
byteswide = (ht+7)/8;
oldwidth = (wd+7)/8;
opt = malloc (1 + byteswide*wd);
outptr = opt; *outptr = '\0';
for (posn = 0; posn < wd; posn++) /* Pick the nth bit off each row */
{
bitmask = 1 << (7 - (posn%8) );
byteoff = posn/8;
outbitoff = 7;
for (i = 0; i < ht ; i++) /* Get from each row... */
{
if (outbitoff < 0) {
outbitoff = 7;
outptr++; *outptr = '\0';
}
outbit =(*(glyph + ((ht-i)-1)*oldwidth + byteoff) & bitmask) != 0;
*outptr |= outbit << outbitoff;
outbitoff--;
}
outptr++; *outptr = '\0';
}
return (opt);
}
special.c
===============================================
#include <stdio.h>
#include "resfonts.h"
#include "imPcodes.h"
#define white(x) (x==' ' || x=='\t')
char *index(),*rindex();
extern int landscape;
typedef char bool;
#define TRUE 1
#define FALSE 0
DoSpecial(bytes,fp) long bytes; FILE *fp;
{
static bool initfonts=FALSE;
bool first;
unsigned long size, tempsize;
FILE *tempin;
char *ai,*bi,*ci,*di,*ei,*fi;
char inchar;
int tempi;
int i;
enum spectype {INSERT, OVERLAY};
enum spectype optype;
ai = bi = (char *) malloc((tempsize = bytes)+1);
while (tempsize--) *bi++=(char) fgetc(fp);
*bi='\0'; /* null out string */
bi = ai;
if (size > 132){
fprintf(stderr, "special command > 132 characters\n");
free(ai);
return;
}
while(white(*bi)) bi++; /* skip leading white space */
ei = ci = bi;
if (!index(ei,'(') || !rindex(ei,')')){ /* check for leading and trailing *\
fprintf(stderr, "incorrect special format\n"); /* prens */
free(ai);
return;
}
while (!white(*ci) && *ci != '(' ) ci++; /* skip non white till ( or white */
*ci='\0'; /* make a string of it */
while (*ei){ /* and lowercase it all */
if (*ei >= 'A' && *ei <= 'Z') *ei = *ei + 'a' - 'A';
ei++;
}
if (!strcmp("insert",bi)) /* find include, overlay, or */
optype = INSERT;
else if (!strcmp("overlay",bi)) /* else it is an error */
optype = OVERLAY;
else {
fprintf(stderr,
"special command operation must be 'insert' or 'overlay'\n");
free(ai);
return;
}
bi = ++ci;
while(white(*bi) || *bi == '(' ) bi++; /* find the file name */
while(white(*bi)) bi++;
ci = bi;
while(!white(*ci) && *ci != ')') ci++; /* delimited by a ) */
*ci = '\0'; /* make a string of it */
if ((tempin = fopen(bi ,"r")) == NULL){ /* open the file */
fprintf(stderr, " can't open %s \n",bi);
free(ai);
return;
}
free(ai); /* no longer need this */
/* UpdPos(); */
ImPressPutc(APUSH);
switch (optype){
/* At the moment, only overlay(file) and insert(file) are
* recognized. We use a slightly modified 'impen' (from Stanford
* via Imagen to produce this stuff, which makes plots come out
* in landscape mode. Hence the rotation and stuff. Other
* Impress-production software may, of course, behave differently...
*/
case OVERLAY:
ImPressPutc(APAGE);
if (landscape) {
ImPressPutc(AMS);
ImPressPutc(0104);
}
else {
ImPressPutc(ASABSV);
ImPressBufWord(2040); /* 8.5 in down */
ImPressPutc(AMS);
ImPressPutc(0147);
ImPressPutc(APAGE);
}
break;
case INSERT:
ImPressPutc(AMS);
if (landscape)
ImPressPutc(0144);
else
ImPressPutc(0147);
break;
}
if (!initfonts) { /* Haven't initialized res fonts */
for (i=0;i<N←RES←FONTS; i++) {
ImPressPutc(ACREFAM);
ImPressPutc(fontTable[i].family);
ImPressPutc(1);
ImPressPutc(0);
ImPressPrintf("%s",fontTable[i].name);
ImPressPutc(0);
}
initfonts=TRUE;
}
first = TRUE;
while ((tempi = getc(tempin)) != EOF) {
inchar = (char) tempi;
if (inchar == '@' && first) { /* remove document control */
while (((inchar = getc(tempin)) != EOF)
&& (inchar != ')' ));
tempi = getc(tempin);
}
first = FALSE;
ImPressPutc(tempi);
}
ImPressPutc(APAGE);
ImPressPutc(APOP);
}
imPcodes.h
===============================================
/* command codes */
#define ASP0 128
#define ASP1 129
#define AM 130
#define AMP 131
#define AMM 132
#define ASABSH 135 /* Absolute horizontal */
#define ASABSV 137 /* Absolute vertical */
#define ASRULE 192
#define ABRULE 193
#define AS 194 /* not implemented yet */
#define AH 195
#define AV 196
#define AN 197
#define ASGLY 198
#define ABGLY 199
#define ADELG 200
#define ADELC 201
#define ADELF 202
#define AFONT 203
#define APAGOR 204
#define AMS 205
#define AROTMS 206
#define AF 207
#define ABSKIP 208
#define AMARGIN 209
#define ASETSP 210
#define APUSH 211
#define APOP 212
#define APAGE 213
#define AEND 219
#define ACREFAM 221
#define ANOP 254
#define AEOF 255
impress.h
===============================================
/*
* impress.h
*
* header file for finding data bases having to do with the imprint printer
* by Bill Nowicki, Stanford University, September 1981
*/
# define PixelsPerInch 240 /* Resolution of the printer being used */
/*
* size of printable area, 8x10.5 inches
*/
# define PixelsPageHeight ( (int)( PixelsPerInch*10.5 ) )
# define PixelsPageWidth ( PixelsPerInch*8 )
/*
* memory parameters
*/
# define K 1024
# define GlyphSize (164*K) /* size of printer's Glyph buffer */
# define InputSize (24*K) /* size of printer's input buffer */
# define GlyphsPerPage (10*K) /* number of distinct glyphs per page */
dvi.h
===============================================
#define SETCHAR0 0
#define SET1 128
#define SETRULE 132
#define PUT1 133
#define PUTRULE 137
#define NOP 138
#define BOP 139
#define EOP 140
#define PUSH 141
#define POP 142
#define RIGHT1 143
#define RIGHT2 144
#define RIGHT3 145
#define RIGHT4 146
#define W0 147
#define W1 148
#define W2 149
#define W3 150
#define W4 151
#define X0 152
#define X1 153
#define X2 154
#define X3 155
#define X4 156
#define DOWN1 157
#define DOWN2 158
#define DOWN3 159
#define DOWN4 160
#define Y0 161
#define Y1 162
#define Y2 163
#define Y3 164
#define Y4 165
#define Z0 166
#define Z1 167
#define Z2 168
#define Z3 169
#define Z4 170
#define FNTNUM0 171
#define FNT1 235
#define FNT2 236
#define FNT3 237
#define FNT4 238
#define XXX1 239
#define XXX2 240
#define XXX3 241
#define XXX4 242
#define FNTDEF1 243
#define FNTDEF2 244
#define FNTDEF3 245
#define FNTDEF4 246
#define PRE 247
#define POST 248
#define POSTPOST 249
#define TRAILER 223 /* Trailing bytes at end of file */
c.h
===============================================
/*
* Standard C macros
*
**********************************************************************
* HISTORY
* 23-Apr-81 Mike Accetta (mja) at Carnegie-Mellon University
* Added "sizeofS" and "sizeofA" macros which expand to the size
* of a string constant and array respectively.
*
**********************************************************************
*/
#define ABS(x) ((x) >= 0 ? (x):-(x))
#define MAX(a,b) ((a) > (b) ? (a):(b))
#define MIN(a,b) ((a) < (b) ? (a):(b))
#define FALSE 0
#define TRUE 1
#define CERROR (-1)
#define sizeofS(string) (sizeof(string) - 1)
#define sizeofA(array) (sizeof(array)/sizeof(array[0]))
font.h
===============================================
/*
* font.h - some definitions for the font manipulation routines
* **CHANGED at Cornell for the dvi-imagen program **
*
* Note that our terminology is slightly different from that of Knuth
* and Parc. Since TROFF assumes that fonts are scalable, we must
* use a single Knuth font (which we call a family, similar to a Parc face),
* at different magnifications (which is what we call a "font").
*/
/*
* the layout of a font information block
* There is one of these for every loaded "font", or
* magnification thereof in Knuthian terms.
*
* Also note the strange units. The design size is in 1/2↑20 point
* units (also called micro-points), and the individual character widths
* are in the TFM file in 1/2↑20 ems units, i.e. relative to the design size.
*/
# define TwoToTheTwenty (1024*1024)
# define MAXCHARS 256 /* make 128 for 7 bit characters */
enum CharStatus {NotThere, Ready, Loaded, Wanted, Kept, InProm};
struct font
{
struct font * next; /* link to next font info block */
int Inumber; /* font number (on Imagen) */
int TeXnumber; /* font number (in DVI file) */
int scale; /* scaled size in DVI units */
int design; /* design size in DVI units */
unsigned char bc; /* beginning char defined */
unsigned char ec; /* ending char defined */
enum CharStatus state[ MAXCHARS ];
/* loaded, existant, or in Prom?? */
/* following are in pixels */
short H[ MAXCHARS ]; /* height for each glyph raster */
short W[ MAXCHARS ]; /* width for each glyph raster */
short Y[ MAXCHARS ]; /* Y-offset for each glyph raster */
short X[ MAXCHARS ]; /* X-offset for each glyph raster */
short pxl←adv[ MAXCHARS ]; /* pixels to move reference point */
long dvi←adv[ MAXCHARS ]; /* DVI units to move reference point */
char *Glyph[ MAXCHARS ]; /* pointers to actual glyph bitmaps */
char fontname[100];
};
extern struct font *fontListHead; /* head of linked list of font structures */
int debug; /* true for debugging information */
ipr.h
===============================================
/*
* ipr.h -- ImPress printer spooler definitions
*
* by Bill Nowicki September 29, 1981
* at Stanford University for Imagen Corporation
*/
# define SPOOLDIR "/usr/spool/ipd" /* the spooling directory */
# define LOCK "/usr/spool/ipd/lock" /* the lock file */
# define LOG "/tmp/implog" /* the error log file */
# define DAEMON "/usr/local/lib/imagen/ipd" /* the unqueuing daemon */
# define PRINTING "/usr/local/lib/imagen/ips" /* the printing program */
# define COMMAND "/usr/local/bin/ipr" /* the command for enqueing */
# define WRITE "/usr/local/lib/imagen/dwrite" /* write to a user */
# define HUMAN "ImPress printer Daemon" /* Human understandable name */
# define KIND "ImPrint" /* kind of printer we use */
# define LOCKTIMEOUT 5*60 /* seconds for the lock timeout */
# define LineSize 128 /* size of a data line */
# include <sys/types.h>
# include <sys/dir.h>
# include <sys/stat.h>
# include <sys/signal.h>
# include <stdio.h>
# include "c.h"
# define bool int
/*
* I am not sure if the following is documented anywhere, so
* I thought I would include it here so nonone else has to go through
* what I did to discover how the standard spooling stuff works.
* I also added a few of my own codes, which should not conflict
* with anything.
*
* Basically there are files in the spool directory of the form:
* dfXXXXXa (where XXXXX is the pid), that have lines with a one
* character code followed by informational lines:
* B treated like F in ipq.c
* C number of copies to print
* F File name to print
* L User's name responsible for printing
* M Mail address to inform when printing is complete
* N User to notify when printing is complete
* P Pages in body (total)
* R "Real" user name for cover sheet
* T "Tag" to identify this job, usually the file name
* U File to unlink after finishing
*/
extern int debug; /* for extra debugging messages */
int Copies; /* number of copies to print */
int Pages; /* number of pages (approx) */
resfonts.h
===============================================
#define TEXTURE←FAMILY 110
#define N←RES←FONTS 8
typedef struct {
short family;
char *name;
} resfont;
resfont fontTable[]= {
{ TEXTURE←FAMILY+0, "textures"},
{ TEXTURE←FAMILY+1, "cmasc8"},
{ TEXTURE←FAMILY+2, "cmasc10"},
{ TEXTURE←FAMILY+3, "cmasc12"},
{ TEXTURE←FAMILY+4, "cmasc14"},
{ TEXTURE←FAMILY+5, "cmasc7"},
{ TEXTURE←FAMILY+6, "cmb18"},
{ TEXTURE←FAMILY+7, "IMAGEN80"}
};